import { TComponent } from '@material/typeing';
import Overlay, { OverlayProps } from '../overlay';

import $style from './index.scss';
import { FC, ReactNode, useEffect, useRef, useState } from 'react';
import { isString } from '@tarojs/shared';
import { hasProperty, isFunction } from '@material/helpers';
import KImage from '../image';
import { pxTransform } from '@tarojs/taro';
import { View, Text } from '@tarojs/components';

export interface ToastBody extends TComponent {
    content: () => ReactNode | ReactNode;
    duration: number;
    position: 'left' | 'top' | 'center' | 'bottom';
    icon: string;
    visible: boolean;
    hasTransition: boolean;
    isOverlayClose: boolean;
    overlayProps: OverlayProps;
}

const IconMap = {
    scuess: 'https://kf-ui.cdn-go.cn/weapp-image/latest/weapp-110/image/cross/common/common_icon_toast_success.png',
    warning:
        'https://kf-ui.cdn-go.cn/weapp-image/latest/weapp-110/image/cross/common/common_icon_toast_alert.png',
    info: '',
    error: ''
};
type IconMapKey = keyof typeof IconMap;
export interface ToastContentType {
    content?: ((val: Omit<ToastContentType, 'content'>) => ReactNode) | ReactNode | string;
    close?: () => void;
    icon?: IconMapKey | string;
    iconSize?: number;
}

export const toastContent = function (props: ToastContentType) {
    const { content, icon, iconSize = pxTransform(108), ...reset } = props;
    if (isString(content) && !icon) {
        return (
            <div className={$style.text}>
                <Text>{content}</Text>
            </div>
        );
    }
    if (isString(content) && icon) {
        const value = hasProperty(IconMap, icon) ? IconMap[icon] : icon;
        return (
            <div className={$style.icon}>
                <KImage
                    src={value}
                    size={iconSize}
                ></KImage>
                <View className={$style['icon-text']}>
                    <Text>{content}</Text>
                </View>
            </div>
        );
    }
    if (isFunction(content)) {
        return content(reset);
    }
    return content;
};

export interface ToastContetnProps extends ToastContentType {
    duration?: number;
    position?: 'left' | 'top' | 'center' | 'bottom';
    hasTransition?: boolean;
    isOverlayClose?: boolean;
    overlayProps?: OverlayProps;
}

export const ToastWrap: FC<ToastContetnProps> = function (props) {
    const {
        overlayProps,
        content,
        icon,
        isOverlayClose = false,
        duration = 3,
        hasTransition = true
    } = props;
    const [visible, setVisible] = useState<boolean>(true);
    const timerRef = useRef<any>(0);
    const closeHandle = () => {
        if (!isOverlayClose) {
            return;
        }
        setVisible((val) => !val);
    };

    const close = () => {
        timerRef.current && clearTimeout(timerRef.current);
        setVisible(false);
    };
    useEffect(() => {
        if (duration === 0) {
            return;
        }

        if (!visible) {
            return;
        }
        timerRef.current && clearTimeout(timerRef.current);
        timerRef.current = setTimeout(() => {
            setVisible((val) => !val);
        }, duration * 1000);
        return () => {
            timerRef.current && clearTimeout(timerRef.current);
        };
    }, [visible, duration]);

    return (
        <Overlay
            className={$style.overlay}
            hasTransition={hasTransition}
            visible={visible}
            {...overlayProps}
            onClick={closeHandle}
        >
            <div className={[$style['inner-wrap']]}>
                <div className={[$style.inner]}>{toastContent({ content, close, icon })}</div>
            </div>
        </Overlay>
    );
};
